package com.tbit.main.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.tbit.main.constant.RedisConstant;
import com.tbit.main.dao.core.MachineDao;
import com.tbit.main.pojo.*;
import com.tbit.main.service.*;
import com.tbit.main.util.DateTimeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author LMY
 * @create 2021-05-25 10:57
 */
@Service("workOrderMachineService")
public class WorkOrderMachineServiceImpl implements WorkOrderMachineService {

    @Autowired
    private CalibrateService calibrateService;
    @Autowired
    private MachineStatusService machineStatusService;
    @Autowired
    private WorkOrderFinishingService workOrderFinishingService;
    @Autowired
    private MachineService machineService;
    @Autowired
    private RedisService redisService;
    @Autowired
    private MachineAbnormalService machineAbnormalService;
    @Autowired
    private MachineFaultService machineFaultService;
    @Autowired
    private MachineDao machineDao;

    @Override
    public Machine getByUseCode(String userCode) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("userCode", userCode);
        return machineDao.getByUseCode(params);
    }

    @Override
    public List<Map<String, Object>> getByPower(Integer accountId, Integer soc, Integer mapType, AccountUser accountUser) {
        List<MachineStatus> machineStatus = machineStatusService.getSocByAccountId(accountId, soc);
        List<Map<String, Object>> mapList = new ArrayList<>();
        /** 校准 */
        if (CollUtil.isNotEmpty(machineStatus)) {
            /**校准*/
            calibrateService.celibrateMachineStatus(machineStatus, mapType);

            /**查询工单*/
            List<WorkOrderFinishing> workOrderFinishingList = workOrderFinishingService.getByAccountIdUserId(accountId, accountUser, null, null, null, null);
            Map<Integer, WorkOrderFinishing> machineOrderState = new HashMap<>();
            for (WorkOrderFinishing workOrderFinishing : workOrderFinishingList) {
                machineOrderState.put(workOrderFinishing.getMachineId(), workOrderFinishing);
            }


            for (MachineStatus ms : machineStatus) {
                Map<String, Object> map = new HashMap<>();
                map.put("machineStatus", ms);
                if (machineOrderState.containsKey(ms.getMachineId())) {
                    map.put("workOrderFinishing", machineOrderState.get(ms.getMachineId()));
                }
                mapList.add(map);
            }
        }

        return mapList;
    }


    @Override
    public List<Map<String, Object>> getByUnuse(Integer accountId, Integer hours, Integer mapType, AccountUser accountUser) {
        /**计算时间*/
        String lastBorrowTime = DateTimeUtil.getHoursAgo(hours);

        List<MachineStatusBorrow> machineStatusBorrows = machineStatusService.getUnUseByAccountId(accountId, lastBorrowTime);

        /**校准*/
        List<Map<String, Object>> mapList = new ArrayList<>();
        if (CollUtil.isNotEmpty(machineStatusBorrows)) {
            calibrateService.celibrateMachineStatusBorrow(machineStatusBorrows, mapType);

            /**查询设备编号和用户码*/
            List<Machine> machines = machineService.getByAccountId(accountId);
            Map<Integer, Machine> machineMap = new HashMap<Integer, Machine>();
            for (Machine machine : machines) {
                machineMap.put(machine.getMachineId(), machine);
            }

            for (MachineStatusBorrow ms : machineStatusBorrows) {
                Machine machine = machineMap.get(ms.getMachineId());
                if (machine != null) {
                    ms.setMachineNO(machine.getMachineNO());
                    ms.setUserCode(machine.getUserCode());
                    ms.setMachineType(machine.getMachineType());
                }
            }

            /**获取调度中挪车状态*/
            for (MachineStatusBorrow msb : machineStatusBorrows) {
                /**挪车*/
                String moveLogString = redisService.get(RedisConstant.REDIS_TER_BIKE_MOVE + msb.getMachineNO());
                if (moveLogString != null) {
                    msb.setMoveState(1);
                    continue;
                }

                /**调度*/
                String dispatchLogString = redisService.get(RedisConstant.REDIS_TER_BIKE_DISPATCH + msb.getMachineNO());
                if (dispatchLogString != null) {
                    msb.setMoveState(2);
                }
            }
        }

        /**查询工单*/
        List<WorkOrderFinishing> workOrderFinishingList = workOrderFinishingService.getByAccountIdUserId(accountId, accountUser, null, null, null, null);
        Map<Integer, Integer> machineOrderState = new HashMap<>();
        for (WorkOrderFinishing workOrderFinishing : workOrderFinishingList) {
            machineOrderState.put(workOrderFinishing.getMachineId(), workOrderFinishing.getState());
        }

        for (MachineStatusBorrow ms : machineStatusBorrows) {
            Map<String, Object> map = new HashMap<>();
            map.put("machineStatusBorrow", ms);
            if (machineOrderState.containsKey(ms.getMachineId())) {
                map.put("workOrderFinishing", machineOrderState.get(ms.getMachineId()));
            }
            mapList.add(map);
        }

        return mapList;
    }

    @Override
    public List<Map<String, Object>> getByAbnormal(Integer accountId, List<Integer> abnormalType, Integer mapType, AccountUser accountUser) {
        List<MachineStatusAbnormal> machineStatusAbnormals = new ArrayList<MachineStatusAbnormal>();

        /**查询异常车辆*/
        List<MachineAbnormal> machineAbnormals = machineAbnormalService.groupByMachineIdAndListType(accountId, abnormalType);

        List<Map<String, Object>> mapList = new ArrayList<>();
        if (machineAbnormals.size() > 0) {
            List<Integer> machineIds = new ArrayList<Integer>();
            Map<Integer, Integer> abnormalMap = new HashMap<Integer, Integer>();
            for (MachineAbnormal ma : machineAbnormals) {
                machineIds.add(ma.getMachineId());
                abnormalMap.put(ma.getMachineId(), ma.getAbnormalType());
            }

            /**查询所有设备状态*/
            List<MachineStatus> machineStatuses = machineStatusService.getByMachineIdBatch(machineIds);

            if (machineStatuses.size() > 0) {
                /**校准*/
                calibrateService.celibrateMachineStatus(machineStatuses, mapType);

                for (MachineStatus ms : machineStatuses) {
                    MachineStatusAbnormal msa = new MachineStatusAbnormal();

                    msa.setMachineId(ms.getMachineId());
                    msa.setMachineNO(ms.getMachineNO());
                    msa.setLon(ms.getLon());
                    msa.setLat(ms.getLat());
                    msa.setLonC(ms.getLonC());
                    msa.setLatC(ms.getLatC());
                    msa.setPosDt(ms.getPosDt());
                    msa.setBatDt(ms.getBatDt());
                    msa.setSocPercent(ms.getSocPercent());
                    msa.setSurplusMileage(ms.getSurplusMileage());

                    /**异常类型*/
                    Integer abnormalTypeCache = abnormalMap.get(ms.getMachineId());
                    if (abnormalTypeCache != null) {
                        msa.setAbnormalType(abnormalTypeCache);
                    }

                    machineStatusAbnormals.add(msa);
                }
            }
        }

        if (machineStatusAbnormals.size() > 0) {
            /**查询设备编号和用户码*/
            if (machineStatusAbnormals.size() > 0) {
                List<Machine> machines = machineService.getByAccountId(accountId);
                Map<Integer, Machine> machineMap = new HashMap<Integer, Machine>();
                for (Machine machine : machines) {
                    machineMap.put(machine.getMachineId(), machine);
                }

                /**查询工单*/
                List<WorkOrderFinishing> workOrderFinishingList = workOrderFinishingService.getByAccountIdUserId(accountId, accountUser, null, null, null, null);
                Map<Integer, Integer> machineOrderState = new HashMap<>();
                for (WorkOrderFinishing workOrderFinishing : workOrderFinishingList) {
                    machineOrderState.put(workOrderFinishing.getMachineId(), workOrderFinishing.getState());
                }

                for (MachineStatusAbnormal ms : machineStatusAbnormals) {
                    Machine machine = machineMap.get(ms.getMachineId());
                    if (machine != null) {
                        ms.setMachineNO(machine.getMachineNO());
                        ms.setUserCode(machine.getUserCode());
                    }
                    Map<String, Object> map = new HashMap<>();
                    map.put("machineStatusAbnormal", ms);
                    if (machineOrderState.containsKey(ms.getMachineId())) {
                        map.put("workOrderFinishing", machineOrderState.get(ms.getMachineId()));
                    }
                    mapList.add(map);
                }
            }
        }

        return mapList;
    }


    @Override
    public List<Map<String, Object>> getByFault(Integer accountId, Integer mapType, List<Integer> faultState, AccountUser accountUser) {
        List<MachineStatusFault> machineStatusFaults = new ArrayList<MachineStatusFault>();

        /**查询所有设备状态*/
        List<MachineStatus> machineStatuses = machineStatusService.getFaultByAccountId(accountId, faultState);

        if (machineStatuses.size() > 0) {
            /**校准*/
            calibrateService.celibrateMachineStatus(machineStatuses, mapType);

            /**查询故障*/
            Map<Integer, MachineFault> machineFaultMap = new HashMap<Integer, MachineFault>();
            List<MachineFault> machineFaults = machineFaultService.getByAccountId(accountId);
            /*machineFaults = machineFaults.stream().filter(machineFault -> {
                //过滤掉疑似故障
                return !Objects.equals(machineFault.getFrom(),4);
            }).collect(Collectors.toList());*/
            for (MachineFault mf : machineFaults) {
                machineFaultMap.put(mf.getMachineId(), mf);
            }

            for (MachineStatus ms : machineStatuses) {
                MachineStatusFault msf = new MachineStatusFault();

                msf.setMachineId(ms.getMachineId());
                msf.setMachineNO(ms.getMachineNO());
                msf.setLon(ms.getLon());
                msf.setLat(ms.getLat());
                msf.setLonC(ms.getLonC());
                msf.setLatC(ms.getLatC());
                msf.setPosDt(ms.getPosDt());
                msf.setBatDt(ms.getBatDt());
                msf.setSocPercent(ms.getSocPercent());
                msf.setSurplusMileage(ms.getSurplusMileage());


                /**故障来源*/
                MachineFault mf = machineFaultMap.get(msf.getMachineId());
                if (mf != null) {
                    msf.setFaultFrom(mf.getFrom());
                    /**故障类型*/
                    msf.setFaultType(mf.getFaults());
                }

                machineStatusFaults.add(msf);
            }
        }

        /**查询工单*/
        List<WorkOrderFinishing> workOrderFinishingList = workOrderFinishingService.getByAccountIdUserId(accountId, accountUser, null, null, null, null);
        Map<Integer, Integer> machineOrderState = new HashMap<>();
        for (WorkOrderFinishing workOrderFinishing : workOrderFinishingList) {
            machineOrderState.put(workOrderFinishing.getMachineId(), workOrderFinishing.getState());
        }

        List<Map<String, Object>> mapList = new ArrayList<>();
        /**查询设备编号和用户码*/
        if (machineStatusFaults.size() > 0) {
            List<Machine> machines = machineService.getByAccountId(accountId);
            Map<Integer, Machine> machineMap = new HashMap<Integer, Machine>();
            for (Machine machine : machines) {
                machineMap.put(machine.getMachineId(), machine);
            }

            for (MachineStatusFault ms : machineStatusFaults) {
                Machine machine = machineMap.get(ms.getMachineId());
                if (machine != null) {
                    ms.setMachineNO(machine.getMachineNO());
                    ms.setUserCode(machine.getUserCode());
                    ms.setMachineType(machine.getMachineType());
                }
                Map<String, Object> map = new HashMap<>();
                map.put("machineStatusFault", ms);
                if (machineOrderState.containsKey(ms.getMachineId())) {
                    map.put("workOrderFinishing", machineOrderState.get(ms.getMachineId()));
                }
                mapList.add(map);
            }
        }

        return mapList;
    }
}
